Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Syphon Filter lens flares by adding compat flag to read back the depth buffer #16907

Merged
merged 3 commits into from
Feb 4, 2023

Conversation

hrydgard
Copy link
Owner

@hrydgard hrydgard commented Feb 4, 2023

This fixes the lens flare occlusion in the Syphon Filter games by reading back the depth buffer from the GPU so that the checks that the game performs work, if a compat flag is set, making these games feel way more "solid" and playable - the flares really were quite distracting. Fixes #10229. Fixes one part of #15923.

Unfortunately, it also slows things down quite drastically on mobile, at least, unless you use the speedhack "Skip GPU readbacks" which will turn this off.

The heuristic about which framebuffer to read from are quite basic too, I have plans to detect that in a safer way, but this does seem to be good enough for these games in particular.

Later I plan to introduce some tricks from #16900 to get the speed back up even with readbacks enabled (though occlusion will be delayed a frame or two, it'll hardly be noticeable).

@hrydgard hrydgard added the GE emulation Backend-independent GPU issues label Feb 4, 2023
@hrydgard hrydgard added this to the v1.15.0 milestone Feb 4, 2023
@hrydgard hrydgard merged commit 1a4a89a into master Feb 4, 2023
@hrydgard hrydgard deleted the readback-refactor branch February 4, 2023 15:20
@Danielet89
Copy link

Is possible fix this Aldo for infra ppspp android & windows? So will fix also on multiplayer games ?

@hrydgard
Copy link
Owner Author

hrydgard commented Feb 4, 2023

I'm not sure what you mean, this fix is not related to muliplayer functionality in any way

void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth) {
if (ShouldDownloadFramebuffer(vfb) && !vfb->memoryUpdated) {
// TODO: Isn't this wrong? Shouldn't we download the prevVfb if anything?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably, I think it didn't have prevVfb as a parameter before and this worked well enough. Maybe this was a consideration for performance? Not sure if it's cheaper to download framebuffer B after rendering to A.

For Danganronpa, anyway, it renders its scenemap every frame iirc.

-[Unknown]

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it's really a curious time to download vfb given that this is when we start rendering to it, isn't it? Though of course, in a way that's fine, we'll just be one frame behind on the readbacks...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, it's only really being used for Danganronpa, which is a game that - at least for these scenemap readbacks - would probably be totally fine with async readbacks.

-[Unknown]

ReadFramebufferToMemory(vfb, 0, 0, vfb->width, vfb->height, RASTER_COLOR);
vfb->usageFlags = (vfb->usageFlags | FB_USAGE_DOWNLOAD | FB_USAGE_FIRST_FRAME_SAVED) & ~FB_USAGE_DOWNLOAD_CLEAR;
} else {
DownloadFramebufferOnSwitch(prevVfb);
}

if (prevVfb && ShouldDownloadFramebufferDepth(prevVfb)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we could skip this if isClearingDepth... not sure if Syphon Filter does that.

-[Unknown]

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well the point of this is to download the framebuffer after it's been renderered to, here we're switching from prevVfb to vfb, so the right check would be if depth has been written during the pass I guess.. Clearing doesn't really enter into the equestion, or am I missing something?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right sorry, I was mixing in the wrong vfb comment and forgot this is checking prevVfb.

-[Unknown]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
GE emulation Backend-independent GPU issues
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Syphon Filter Dark Mirror - lights are visible through buildings
3 participants